package org.luckystrophe.snowtoms.adapter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
import org.json.JSONObject;
import org.luckystrophe.snowtoms.FullsizeImageActivity_;
import org.luckystrophe.snowtoms.MainActivity;
import org.luckystrophe.snowtoms.MainActivity_;
import org.luckystrophe.snowtoms.R;
import org.luckystrophe.snowtoms.ReplyActivity_;
import org.luckystrophe.snowtoms.model.JsonRequest;
import org.luckystrophe.snowtoms.model.SNSPost;
import org.luckystrophe.snowtoms.model.impl.DeleteMessageRequest;
import org.luckystrophe.snowtoms.model.impl.GetMessageList;
import org.luckystrophe.snowtoms.model.impl.RequestDislike;
import org.luckystrophe.snowtoms.model.impl.RequestLike;
import org.luckystrophe.snowtoms.model.impl.UnDislikeRequest;
import org.luckystrophe.snowtoms.model.impl.UnLikeRequest;
import org.luckystrophe.snowtoms.model.impl.UserPost;
import org.luckystrophe.snowtoms.pref.UserPreference_;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.androidquery.AQuery;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.widget.FacebookDialog;
import com.googlecode.androidannotations.annotations.AfterInject;
import com.googlecode.androidannotations.annotations.Background;
import com.googlecode.androidannotations.annotations.Bean;
import com.googlecode.androidannotations.annotations.EBean;
import com.googlecode.androidannotations.annotations.RootContext;
import com.googlecode.androidannotations.annotations.UiThread;
import com.googlecode.androidannotations.annotations.sharedpreferences.Pref;

@EBean
public class AdapterMessages extends BaseAdapter implements OnClickListener {

	@RootContext
	Context context;

	@Bean(GetMessageList.class)
	JsonRequest getMessageList;

	@Bean(RequestLike.class)
	JsonRequest likeRequest;

	@Bean(UnLikeRequest.class)
	JsonRequest unLikeRequest;

	@Bean(RequestDislike.class)
	JsonRequest dislikeRequest;

	@Bean(UnDislikeRequest.class)
	JsonRequest unDislikeRequest;

	@Bean(DeleteMessageRequest.class)
	JsonRequest deleteMessageRequest;

	@Pref
	UserPreference_ pref;

	private ArrayList<UserPost> userPosts;

	private MessageHolder messageHolder;

	private AQuery aQuery;

	private static final String SNOW_CONTEST_URL = "http://wow.seoul.go.kr/event/13471210hope/write.jsp";

	private static final List<String> PERMISSIONS = Arrays.asList("publish_actions");

	public static final int LATEST_MESSAGES = 1;

	public static final int MORE_MESSAGES = 2;

	private Toast pleaseLoginToast = null;

	@AfterInject
	public void afterInject() {
		userPosts = new ArrayList<UserPost>();
	}

	public ArrayList<UserPost> getMessages(long startOffset) {
		((GetMessageList) getMessageList).setStartOffset(startOffset);
		JSONObject resultJo = new JSONObject();
		try {
			resultJo = getMessageList.sendJsonRequest();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return ((GetMessageList) getMessageList).parseJSONMEssage(resultJo);
	}

	public long afterGetMessages(int flag, ArrayList<UserPost> resultPosts) {
		if (flag == LATEST_MESSAGES) {
			userPosts = resultPosts;
		} else {
			userPosts.addAll(resultPosts);
		}
		this.notifyDataSetChanged();
		return getLastIndex();
	}

	public long getLastIndex() {
		return (userPosts.size() == 0) ? 0L : userPosts.get(getCount() - 1).getPostNo();
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		if (convertView == null) {
			messageHolder = new MessageHolder();
			LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			convertView = inflater.inflate(R.layout.row_sns, null);

			messageHolder.iv_postImg = (ImageView) convertView.findViewById(R.id.iv_postimg);
			messageHolder.iv_userThumbnail = (ImageView) convertView.findViewById(R.id.iv_userthumbnail);
			messageHolder.tv_userId = (TextView) convertView.findViewById(R.id.tv_userid);
			messageHolder.tv_userComment = (TextView) convertView.findViewById(R.id.tv_usercomment);
			messageHolder.tv_userLocation = (TextView) convertView.findViewById(R.id.tv_userlocation);
			messageHolder.tv_postDate = (TextView) convertView.findViewById(R.id.tv_messageDate);
			messageHolder.btn_like = (ToggleButton) convertView.findViewById(R.id.btn_like);
			messageHolder.btn_dislike = (ToggleButton) convertView.findViewById(R.id.btn_dislike);
			messageHolder.btn_share = (Button) convertView.findViewById(R.id.btn_share);
			messageHolder.btn_reply = (Button) convertView.findViewById(R.id.btn_reply);
			messageHolder.btn_deleteOrAlter = (Button) convertView.findViewById(R.id.btn_deleteoralter);
			messageHolder.rl_deleteoralter = (RelativeLayout) convertView.findViewById(R.id.rl_deleteoralter);

			convertView.setTag(messageHolder);

		} else {
			messageHolder = (MessageHolder) convertView.getTag();
		}

		aQuery = new AQuery(convertView);
		UserPost post = userPosts.get(position);

		if (post.getImgSrc().indexOf("null") != -1) {
			aQuery.id(messageHolder.iv_postImg).visibility(View.GONE);
		} else {
			aQuery.id(messageHolder.iv_postImg).visibility(View.VISIBLE)
					.image(post.getImgSrc(), true, true, 0, R.drawable.no_post_image).clicked(this).tag(post);
		}

		Bitmap preset = aQuery.getCachedImage(post.getUserThumbnail());
		aQuery.id(messageHolder.iv_userThumbnail).image(post.getUserThumbnail(), false, false, 0, 0, preset,
				AQuery.FADE_IN_NETWORK);
		aQuery.id(messageHolder.tv_userId).text(post.getName());
		messageHolder.tv_userComment.setMovementMethod(LinkMovementMethod.getInstance());
		aQuery.id(messageHolder.tv_userComment).text(Html.fromHtml(post.getComment().toString()));
		aQuery.id(messageHolder.tv_postDate).text(post.getPostDate());
		aQuery.id(messageHolder.tv_userLocation).text(post.getLocationAndLikes());
		aQuery.id(messageHolder.btn_like).checked(post.isLike()).clicked(this).tag(post);
		aQuery.id(messageHolder.btn_dislike).checked(post.isDislike()).clicked(this).tag(post);
		aQuery.id(messageHolder.btn_share).clicked(this).tag(post);
		aQuery.id(messageHolder.btn_reply).clicked(this).tag(post);
		aQuery.id(messageHolder.btn_deleteOrAlter).clicked(this).tag(post);
		aQuery.id(messageHolder.rl_deleteoralter).clicked(this).tag(post).visibility(post.isMyPost(pref.usrId().get()));

		return convertView;
	}

	@Override
	public int getCount() {
		return userPosts.size();
	}

	@Override
	public UserPost getItem(int position) {
		return userPosts.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	private void openReplyActivity(UserPost userPost) {
		Intent i = new Intent(context, ReplyActivity_.class);
		i.putExtra("msgId", userPost.getPostNo());
//		context.startActivity(i);
		((MainActivity_)context).startActivityForResult(i, MainActivity.REPLY_ACTIVITY_RESULT_CODE);
	}

	@Override
	public void onClick(View v) {
		UserPost userPost = (UserPost) v.getTag();
		switch (v.getId()) {
		case R.id.btn_reply:
			if (pref.usrId().get() == 0L) {
				showPleasLoginToast();
				return;
			}
			openReplyActivity(userPost);
			break;

		case R.id.btn_share:
			if (pref.collaboId().get().length() == 0) {
				showPleasLoginToast();
				return;
			}
			publishFeed(userPost);
			break;

		case R.id.btn_like:
			if (pref.usrId().get() == 0L) {
				showPleasLoginToast();
				((ToggleButton) v).setChecked(false);
				return;
			}
			likeRequest(userPost, (ToggleButton) v);
			break;

		case R.id.btn_dislike:
			if (pref.usrId().get() == 0L) {
				showPleasLoginToast();
				((ToggleButton) v).setChecked(false);
				return;
			}
			dislikeRequest(userPost, (ToggleButton) v);
			break;
		case R.id.iv_postimg:
			if (userPost.getMsgType() == SNSPost.MESSAGE_TYPE_NOTICE) {
				clickImageForNotice();
			} else {
				clickImage(userPost);
			}
			break;

		case R.id.btn_deleteoralter:
			clickOptionMenu(userPost);
			break;

		case R.id.rl_deleteoralter:
			clickOptionMenu(userPost);
			break;

		// case R.id.tv_usercomment:
		// clickImage(userPost);
		// break;
		}
	}

	@Background
	public void likeRequest(UserPost userPost, ToggleButton v) {
		userPost.setLike(!userPost.isLike());
		if (userPost.isLike()) {
			((RequestLike) likeRequest).setMsgId(userPost);
			JSONObject resultJo = new JSONObject();
			try {
				resultJo = likeRequest.sendJsonRequest();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			resultLike(resultJo, v);
		} else {
			((UnLikeRequest) unLikeRequest).setMsgId(userPost);
			JSONObject resultJo = new JSONObject();
			try {
				resultJo = unLikeRequest.sendJsonRequest();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			resultLike(resultJo, v);
		}
	}

	@Background
	public void dislikeRequest(UserPost userPost, ToggleButton v) {
		userPost.setDislike(!userPost.isDislike());
		if (userPost.isDislike()) {
			((RequestDislike) dislikeRequest).setMsgId(userPost);
			JSONObject resultJo = new JSONObject();
			try {
				resultJo = dislikeRequest.sendJsonRequest();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			resultDisLike(resultJo, v);
		} else {
			((UnDislikeRequest) unDislikeRequest).setMsgId(userPost);
			JSONObject resultJo = new JSONObject();
			try {
				resultJo = unDislikeRequest.sendJsonRequest();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			resultDisLike(resultJo, v);
		}
	}

	@UiThread
	void resultDisLike(JSONObject jo, ToggleButton v) {
		try {
			int resultCode = jo.getInt("resultCode");
			if (resultCode != 1) {
				v.setChecked(!v.isChecked());
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	@UiThread
	void resultLike(JSONObject jo, ToggleButton v) {
		try {
			int resultCode = jo.getInt("resultCode");
			if (resultCode != 1) {
				v.setChecked(!v.isChecked());
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	public void clickImage(UserPost userPost) {
		Intent i = new Intent(context, FullsizeImageActivity_.class);
		i.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
		i.putExtra("imageSrc", userPost.getImgSrc());
		i.putExtra("comment", userPost.getComment());
		i.putExtra("location", userPost.getUserLocation());
		context.startActivity(i);
		((Activity) context).overridePendingTransition(R.anim.fadein, R.anim.deltazero);
	}

	public void clickImageForNotice() {
		Intent i = new Intent(Intent.ACTION_VIEW);
		Uri uri = Uri.parse(SNOW_CONTEST_URL);
		i.setData(uri);
		context.startActivity(i);
	}

	public void publishFeed(UserPost post) {
		Session session = Session.getActiveSession();
		if (session != null && session.isOpened()) {

			// Check for publish permissions
			List<String> permissions = session.getPermissions();
			if (!isSubsetOf(PERMISSIONS, permissions)) {
				Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(
						(MainActivity_) context, PERMISSIONS);
				session.requestNewPublishPermissions(newPermissionsRequest);
				return;
			}
			FacebookDialog fDialog = new FacebookDialog.ShareDialogBuilder((MainActivity_) context)
					.setLink(SNOW_CONTEST_URL).setName(post.getComment()).setPicture(post.getImgSrc())
					.setCaption("눈치해치는 안드로이드 전용 서비스입니다.").build();
			UiLifecycleHelper uiHelper = new UiLifecycleHelper((MainActivity_) context, new Session.StatusCallback() {
				@Override
				public void call(Session session, SessionState state, Exception exception) {
					// TODO Auto-generated method stub
				}
			});
			uiHelper.trackPendingDialogCall(fDialog.present());
		}
	}

	public void clickOptionMenu(UserPost userPost) {
		if (userPost.getUserId() != pref.usrId().get()) {
			return;
		}
		final long selectedMsgId = userPost.getPostNo();

		// final CharSequence[] items = { "수정", "삭제" };
		final CharSequence[] items = { "삭제" };

		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setItems(items, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int item) {
				if (item == 0) {
					showDeleteMessageDialog(selectedMsgId);
				}
			}
		});
		AlertDialog alert = builder.create();

		alert.show();

	}

	private void showDeleteMessageDialog(final long msgId) {
		AlertDialog.Builder alert_confirm = new AlertDialog.Builder(context);
		alert_confirm.setMessage("메시지를 삭제하시겠습니까?").setPositiveButton("확인", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				deleteMessage(msgId);
			}
		}).setNegativeButton("취소", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				return;
			}
		});
		AlertDialog alert = alert_confirm.create();
		alert.show();
	}

	@Background
	public void deleteMessage(long msgId) {
		int resultCode = 0;
		try {
			((DeleteMessageRequest) deleteMessageRequest).setMsgId(msgId);
			JSONObject jo = deleteMessageRequest.sendJsonRequest();
			resultCode = jo.getInt("resultCode");
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			afterDeleteMessage(resultCode);
		}
	}

	@UiThread
	public void afterDeleteMessage(int resultCode) {
		if (resultCode == 1) {
			refreshMessage();
		} else {
			Toast.makeText(context, "에러가 발생했습니다.", Toast.LENGTH_SHORT).show();
		}
	}

	@Background
	public void refreshMessage() {
		afterRefreshMessage(getMessages(0L));
	}

	@UiThread
	public void afterRefreshMessage(ArrayList<UserPost> messages) {
		afterGetMessages(LATEST_MESSAGES, messages);
	}

	private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
		for (String string : subset) {
			if (!superset.contains(string)) {
				return false;
			}
		}
		return true;
	}

	public class MessageHolder {
		ImageView iv_postImg;
		ImageView iv_userThumbnail;
		TextView tv_userId;
		TextView tv_userComment;
		TextView tv_userLocation;
		TextView tv_postDate;
		ToggleButton btn_like;
		ToggleButton btn_dislike;
		Button btn_share;
		Button btn_reply;
		Button btn_deleteOrAlter;
		RelativeLayout rl_deleteoralter;
	}

	private void showPleasLoginToast() {
		if (pleaseLoginToast == null) {
			pleaseLoginToast = Toast.makeText(context, context.getResources().getString(R.string.pleaseLogin),
					Toast.LENGTH_SHORT);
		}

		pleaseLoginToast.show();
	}
}
